using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.IO.Compression;
using System.Web;
using System.Drawing;
using System.Xml.Schema;
using System.Xml;

namespace Barbar.MapReport.HtmlRender.Shapes {
  internal abstract class Shape : IShape {
    private int m_Width;
    private int m_Height;
    private Rectangle m_Rect;

    public Shape() {
      m_Rect = new Rectangle();
    }

    public Shape(int width, int height) {
      m_Width = width;
      m_Height = height;
      m_Rect = new Rectangle(0, 0, m_Width - 1, m_Height - 1);
    }

    protected Rectangle Rectangle {
      get { return m_Rect; }
    }

    #region IShape Members

    public virtual int Width {
      get { return m_Width; }
      set {
        m_Width = value;
        m_Rect = new Rectangle(0, 0, m_Width - 1, m_Height - 1);
      }
    }

    public virtual int Height {
      get { return m_Height; }
      set {
        m_Height = value;
        m_Rect = new Rectangle(0, 0, m_Width - 1, m_Height - 1);
      }
    }

    public abstract void Draw(System.Drawing.Graphics graphics);

    public string Serialize() {
      string result;
      using (MemoryStream stream = new MemoryStream()) {
        using (StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(false))) {
          using (XmlTextWriter writer = new XmlTextWriter(streamWriter)) {
            WriteXml(writer);
            writer.Close();
          }
          streamWriter.Close();
        }
        result = HttpUtility.UrlEncode(Encoding.UTF8.GetString(stream.ToArray()));
        stream.Close();
      }
      return result;
    }

    #endregion

    public static IShape Deserialize(string rawData, Type type) {
      IShape result = (IShape)type.GetConstructor(Type.EmptyTypes).Invoke(null);
      byte[] buffer = Encoding.UTF8.GetBytes(rawData);
      using (MemoryStream stream = new MemoryStream(buffer)) {
        using (XmlTextReader reader = new XmlTextReader(stream)) {
          result.ReadXml(reader);
          reader.Close();
        }
        stream.Close();
      }
      return result;
    }

    #region IXmlSerializable Members

    public XmlSchema GetSchema() {
      throw new NotImplementedException();
    }

    public virtual void ReadXml(XmlReader reader) {
      Width = XmlConvert.ToInt32(reader.GetAttribute("w"));
      Height = XmlConvert.ToInt32(reader.GetAttribute("h"));
    }

    public virtual void WriteXml(XmlWriter writer) {
      writer.WriteAttributeString("w", XmlConvert.ToString(Width));
      writer.WriteAttributeString("h", XmlConvert.ToString(Height));
    }

    #endregion
  }
}
